/**
 * $Revision: 1.0 $
 * $Author: Geln Yang $
 * $Date: Jun 24, 2009 9:25:43 AM $
 *
 * Author: Eric Yang
 * Date  : Jun 24, 2009 9:25:43 AM
 *
 */
package c4j.file;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author Eric Yang
 * @version 1.0
 */
public class FileUtils {

	private static final String yyyyMMdd = "yyyyMMdd";

	public static final String DEFAULT_CHARSET = "utf-8";

	public static String getFileName(String filePath) {
		return filePath.substring(filePath.lastIndexOf("\\") + 1, filePath.length());
	}

	public static String getFileDir(String filePath) {
		return filePath.substring(0, filePath.lastIndexOf("\\") + 1);
	}

	public static String getFileNameSuffix(String fileName) {
		int suffixIndex = fileName.lastIndexOf(".");
		if (suffixIndex == -1)
			return "";
		return fileName.substring(suffixIndex, fileName.length()).toLowerCase();
	}

	public static String getFileNamePrefix(String fileName) {
		int prefixIndex = fileName.lastIndexOf(".");
		if (prefixIndex == -1)
			return fileName;
		return fileName.substring(0, fileName.lastIndexOf("."));
	}

	public static void createFile(String fullFilePath) throws IOException {
		File file = new File(fullFilePath);
		if (!file.exists()) {
			initDirPath(getFileDir(fullFilePath));
			file.createNewFile();
		}
	}

	public static String initDirPath(String path) {
		if (path == null)
			throw new IllegalArgumentException("Please initialize incoming message source folder path!");

		if (!path.endsWith(File.separator))
			path += File.separator;

		File file = new File(path);
		if (!file.exists())
			file.mkdirs();
		return path;
	}

	public static String getTodayStoreDir(String baseDir) {
		baseDir = initDirPath(baseDir);
		String today = new SimpleDateFormat(yyyyMMdd).format(new Date());
		return initDirPath(baseDir + today);
	}

	/**
	 * @param path :
	 *            a valid file directory
	 * @param pattern
	 *            :filename matche regular Expression pattern if you want to matches all files<br>
	 *            ,please set pattern = null. assume you want to matches all "*.wfx",you can set pattern = ".+\\.wfx";
	 * @return a array of file names
	 * @throws IOException
	 */
	public static String[] listFilenames(String path, final String pattern) throws IOException {
		File dir = new File(path);
		if (!dir.isDirectory() || !dir.exists()) {
			throw new IOException(path + " is not a valid path!");
		}
		if (pattern == null) {
			return dir.list();
		} else {
			return dir.list(new FilenameFilter() {

				public boolean accept(File dir, String fileName) {
					return fileName.matches(pattern);
				}

			});
		}
	}

	/**
	 * @param path :
	 *            a valid file directory
	 * @param pattern
	 *            :filename matche regular Expression pattern if you want to matches all files<br>
	 *            ,please set pattern = null. assume you want to matches all "*.wfx",you can set pattern = ".+\\.wfx";
	 * @return a array of files
	 * @throws IOException
	 */
	public static File[] listFiles(String path, final String pattern) throws IOException {
		File dir = new File(path);
		if (!dir.isDirectory() || !dir.exists()) {
			throw new IOException(path + " is not a valid path!");
		}
		if (pattern == null) {
			return dir.listFiles();
		} else {
			return dir.listFiles(new FilenameFilter() {

				public boolean accept(File dir, String fileName) {
					return fileName.matches(pattern);
				}

			});
		}
	}

	/**
	 * copy sourcefile to destfile,if the destfile is exists,it will override it! <br>
	 * note:sourcefile must be a valid full fileName,and the destDir must exist,otherwise your will receive an
	 * IOException.
	 * 
	 * @param sourceFilePath
	 * @param destFilePath
	 * @throws IOException
	 */
	public static void copyTo(String sourceFilePath, String destFilePath) throws IOException {
		InputStream is = null;
		OutputStream fs = null;
		try {
			is = new FileInputStream(sourceFilePath);
			createFile(destFilePath);
			fs = new FileOutputStream(destFilePath);
			int byteread;
			byte[] buffer = new byte[1444];
			while ((byteread = is.read(buffer)) != -1) {
				fs.write(buffer, 0, byteread);
			}
		} finally {
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
				}
			}
			if (fs != null) {
				try {
					fs.close();
				} catch (IOException e) {
				}
				;
			}
		}
	}

	public static void deleteDir(String dir) throws IOException {
		File file = new File(dir);
		if (!file.isDirectory() || !file.exists()) {
			throw new IOException(dir + " is not a valid dir!");
		}
		file.delete();
	}

	public static void moveFile(String sourceFilePath, String destFilePath) throws IOException {
		copyTo(sourceFilePath, destFilePath);
		deleteFile(sourceFilePath);
	}

	public static void moveFile(File file, String destFilePath) throws IOException {
		copyTo(file.getAbsolutePath(), destFilePath);
		deleteFile(file);
	}

	public static void deleteFile(String fullFileName) throws IOException {
		File file = new File(fullFileName);
		if (!file.isFile() || !file.exists()) {
			throw new IOException(fullFileName + " is not a valid file!");
		}
		file.delete();
	}

	public static void deleteFile(File file) throws IOException {
		if (!file.isFile() || !file.exists()) {
			throw new IOException(file.getAbsolutePath() + " is not a valid file!");
		}
		file.delete();
	}

	public static void renameFile(String fullFilename, String fullNewFilename) throws IOException {
		File file = new File(fullFilename);
		if (!file.isFile() || !file.exists()) {
			throw new IOException(fullFilename + " is not a valid file!");
		}
		file.renameTo(new File(fullNewFilename));
	}

	public static byte[] getFileContent(File file) throws IOException {
		byte[] result = null;
		FileInputStream in = null;
		try {
			in = new FileInputStream(file);
			BufferedInputStream bin = null;
			try {
				bin = new BufferedInputStream(in);
				ByteArrayOutputStream bo = new ByteArrayOutputStream(bin.available());
				byte[] buffer = new byte[1024];
				int len = -1;
				while ((len = bin.read(buffer, 0, 1024)) > 0) {
					bo.write(buffer, 0, len);
				}
				result = bo.toByteArray();
			} finally {
				if (bin != null) {
					try {
						bin.close();
					} catch (IOException e) {
					}
				}
			}
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
				}
			}
		}

		return result;
	}

	private static void writeBufferedTextFile(File file, String charsetName, ITextFileWriter ifileWriter)
			throws IOException {
		FileOutputStream fo = null;
		try {
			fo = new FileOutputStream(file);
			OutputStreamWriter ow = null;
			try {
				ow = new OutputStreamWriter(fo, charsetName);
				BufferedWriter bw = null;
				try {
					bw = new BufferedWriter(ow);
					ifileWriter.write(bw);
				} finally {
					if (bw != null) {
						try {
							bw.close();
						} catch (IOException e) {
						}
					}
				}
			} finally {
				if (ow != null) {
					try {
						ow.close();
					} catch (IOException e) {
					}
				}
			}
		} finally {
			if (fo != null) {
				try {
					fo.close();
				} catch (IOException e) {
				}
			}
		}
	}

	public static File writeBufferedTempTextFile(String prefix, String suffix, String charsetName,
			ITextFileWriter ifileWriter) throws IOException {
		File tempFile = File.createTempFile(prefix, suffix);
		writeBufferedTextFile(tempFile, charsetName, ifileWriter);
		return tempFile;
	}

	public static File writeBufferedTextFile(String fullFileName, String charsetName, ITextFileWriter ifileWriter)
			throws IOException {
		File file = new File(fullFileName);
		writeBufferedTextFile(file, charsetName, ifileWriter);
		return file;
	}

	public static void readBufferedTextFile(InputStream in, String charsetName, ITextFileReader ifileReader)
			throws IOException {
		InputStreamReader inr = null;
		try {
			inr = new InputStreamReader(in, charsetName);
			BufferedReader br = null;
			try {
				br = new BufferedReader(inr);
				ifileReader.read(br);
			} finally {
				if (br != null) {
					try {
						br.close();
					} catch (IOException e) {
					}
				}
			}
		} finally {
			if (inr != null) {
				try {
					inr.close();
				} catch (IOException e) {
				}
			}
		}
	}

	public static void readBufferedTextFile(String fullFileName, ITextFileReader ifileReader) throws IOException {
		readBufferedTextFile(fullFileName, DEFAULT_CHARSET, ifileReader);
	}

	public static void readBufferedTextFile(String fullFileName, String charsetName, ITextFileReader ifileReader)
			throws IOException {
		File inputFile = new File(fullFileName);
		if (inputFile.isDirectory() || !inputFile.exists()) {
			throw new IOException(fullFileName + " is not a vaild file!");
		}
		FileInputStream fin = null;
		try {
			fin = new FileInputStream(inputFile);
			readBufferedTextFile(fin, charsetName, ifileReader);
		} finally {
			if (fin != null) {
				try {
					fin.close();
				} catch (IOException e) {
				}
			}
		}
	}

	public static String getPostfix(String filename) {
		if (filename == null)
			return null;
		int pos = filename.lastIndexOf('.');
		if (pos == -1)
			return null;
		return filename.substring(filename.lastIndexOf('.') + 1);
	}
}
